using System;
using System.Collections.Generic;
using Castle.ActiveRecord;

namespace DecisionMaking.Domain.Reports
{
    public class ReportDao
    {
        public IList<CompetitionResultReportEntry> GetAverageProportionOfCorrectInferences(int? definitionId, int? environmentId, Guid? simulationId)
        {
            var session = ActiveRecordMediator.GetSessionFactoryHolder().CreateSession(typeof (ActiveRecordBase));

            try
            {
                var hql =
                    @"select new CompetitionResultReportEntry(d.Name, a.PctOfCuesKnown, avg(e.AvgAccuracy))
                            from AlgorithmExecutionOutcome e
                            inner join e.AlgorithmDefinition d
                            inner join e.Agent a
                            where 1 = 1 ";

                if (definitionId.HasValue)
                {
                    hql += " and d.id = " + definitionId.Value;
                }
                if (environmentId.HasValue)
                {
                    hql += " and e.Simulation.Environment.Id = " + environmentId.Value;
                }
                if (simulationId.HasValue)
                {
                    hql += " and e.Simulation.Id = '" + simulationId.Value + "'";
                }

                hql += " group by d.Name, a.PctOfCuesKnown";

                return session.CreateQuery(hql).List<CompetitionResultReportEntry>();
            }
            finally
            {
                ActiveRecordMediator.GetSessionFactoryHolder().ReleaseSession(session);
            }
        }

        public IList<AlgorithmPerformanceReportEntry> GetSingleAlgorithmPerfomance(int definitionId, int? environmentId, Guid? simulationId)
        {
            var session = ActiveRecordMediator.GetSessionFactoryHolder().CreateSession(typeof(ActiveRecordBase));

            try
            {
                var hql =
                    @"select new AlgorithmPerformanceReportEntry(e.NumOfCandidatesRecognized, a.PctOfCuesKnown, e.AvgAccuracy) 
                            from AlgorithmExecutionOutcome e
                            inner join e.AlgorithmDefinition d
                            inner join e.Agent a
                            where d.id = " + definitionId;

                if (environmentId.HasValue)
                {
                    hql += " and e.Simulation.Environment.Id = " + environmentId.Value;
                }
                if (simulationId.HasValue)
                {
                    hql += " and e.Simulation.Id = '" + simulationId.Value + "'";
                }

                return session.CreateQuery(hql).List<AlgorithmPerformanceReportEntry>();
            }
            finally
            {
                ActiveRecordMediator.GetSessionFactoryHolder().ReleaseSession(session);
            }            
        }

        public IList<AlgorithmPerformanceReportEntry> GetAlgorithmPerfomance(int? environmentId, Guid? simulationId)
        {
            var session = ActiveRecordMediator.GetSessionFactoryHolder().CreateSession(typeof(ActiveRecordBase));

            try
            {
                var hql =
                    @"select new AlgorithmPerformanceReportEntry(d.Name, e.NumOfCandidatesRecognized, e.AvgAccuracy)
                            from AlgorithmExecutionOutcome e
                            inner join e.AlgorithmDefinition d
                            inner join e.Agent a
                            where 1=1";

                if (environmentId.HasValue)
                {
                    hql += " and e.Simulation.Environment.Id = " + environmentId.Value;
                }
                if (simulationId.HasValue)
                {
                    hql += " and e.Simulation.Id = '" + simulationId.Value + "'";
                }

                return session.CreateQuery(hql).List<AlgorithmPerformanceReportEntry>();
            }
            finally
            {
                ActiveRecordMediator.GetSessionFactoryHolder().ReleaseSession(session);
            }
        }
    }

}